//
//  ViewModel.swift
//  Sorts
//
//  Created by lhc on 2023/12/8.
//

import Foundation
import Combine
import SwiftUI

@Observable
class ViewModel {
    private var cancelables = Set<AnyCancellable>()
    
    var unsortArray = [Int]()
    
    var dataArray = [NumberModel]()
    
    var operators = [(OperatorType, (Int, Int))]()
    
    
    
    init() {
        
        reset()
        
        Timer.publish(every: 1, on: .main, in: .default).autoconnect()
            .sink { _ in
                self.timerAction()
            }
            .store(in: &cancelables)
    }
    
    private func reset() {
        unsortArray = BaseSort.generateList(length: 20, floor: 1, celling: 20)
        operators.removeAll()
        dataArray = unsortArray.map{ num in
            NumberModel(num: num)
        }
    }
    
    private func timerAction() {
        if operators.first != nil {
            let op = operators.removeFirst()
            withAnimation {
                switch op.0 {
                case .exchange:
                    let temp = self.dataArray[op.1.0]
                    self.dataArray[op.1.0] = self.dataArray[op.1.1]
                    self.dataArray[op.1.1] = temp
                case .assign:
                    self.dataArray[op.1.0] = NumberModel(num: op.1.1)
                }
                
            }
        }
    }
    
    func selectSortClick() {
        reset()
        
        let s = SelectSort(list: unsortArray)
        s.sort { type , nums in
            operators.append((type, nums))
        }
    }
    
    func insertSortClick() {
        reset()
        
        let s = InsertSort(list: unsortArray)
        s.sort { type , nums in
            operators.append((type, nums))
        }
    }
    
    func insertExchangeSortClick() {
        reset()
        
        let s = InsertExchangeSort(list: unsortArray)
        s.sort { type, nums in
            operators.append((type, nums))
        }
    }
    
    func bubbleSortClick() {
        reset()
        
        let s = BubbleSort(list: unsortArray)
        s.sort { type, nums in
            operators.append((type, nums))
        }
    }
    
    func mergeSortClick() {
        reset()
        
        let s = MergeSort(list: unsortArray)
        s.action = {[weak self] type, nums in
            self?.operators.append((type, nums))
        }
        s.sort()
    }
    
    func quickSortOneWaysClick() {
        reset()
        
        let s = QuickSortOneWays(list: unsortArray)
        s.action = {[weak self] type, nums in
            if nums.0 != nums.1 {
                self?.operators.append((type, nums))
            }
        }
        s.sort()
    }
    
    func quickSortTwoWaysClick() {
        reset()
        
        let s = QuickSortTwoWays(list: unsortArray)
        s.action = {[weak self] type, nums in
            if nums.0 != nums.1 {
                self?.operators.append((type, nums))
            }
        }
        s.sort()
    }
    
    func quickSortThreeWaysClick() {
        reset()
        
        let s = QuickSortThreeWays(list: unsortArray)
        s.action = {[weak self] type, nums in
            if nums.0 != nums.1 {
                self?.operators.append((type, nums))
            }
        }
        s.sort()
    }
}
